package db

import (
	"database/sql"
	"fmt"
	"image-server/config"
	"log"
	"os"
	"strings"
	"time"
)

func InitDB() error {
	// 1. 连接到MySQL服务器（不指定具体数据库）
	serverDSN := fmt.Sprintf("%s:%s@tcp(%s:%s)/?charset=utf8mb4&parseTime=true",
		config.DBConfigInstance.User, config.DBConfigInstance.Password,
		config.DBConfigInstance.Host, config.DBConfigInstance.Port)

	serverDB, err := sql.Open("mysql", serverDSN)
	if err != nil {
		return fmt.Errorf("无法打开服务器连接: %w", err)
	}
	defer serverDB.Close()

	// 测试服务器连接
	if err := serverDB.Ping(); err != nil {
		return fmt.Errorf("服务器连接失败: %w", err)
	}

	// 2. 检查数据库是否存在
	var dbExists int
	checkSQL := "SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ?"
	err = serverDB.QueryRow(checkSQL, config.DBConfigInstance.Name).Scan(&dbExists)
	if err != nil {
		return fmt.Errorf("检查数据库失败: %w", err)
	}

	// 3. 不存在则创建数据库
	if dbExists == 0 {
		log.Printf("创建数据库: %s", config.DBConfigInstance.Name)
		createSQL := fmt.Sprintf("CREATE DATABASE %s CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
			config.DBConfigInstance.Name)
		if _, err := serverDB.Exec(createSQL); err != nil {
			return fmt.Errorf("创建数据库失败: %w", err)
		}
	}

	// 4. 连接到目标数据库
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true",
		config.DBConfigInstance.User, config.DBConfigInstance.Password,
		config.DBConfigInstance.Host, config.DBConfigInstance.Port,
		config.DBConfigInstance.Name)

	config.DB, err = sql.Open("mysql", dsn)
	if err != nil {
		return fmt.Errorf("无法打开数据库连接: %w", err)
	}

	// 测试数据库连接
	if err := config.DB.Ping(); err != nil {
		return fmt.Errorf("数据库连接失败: %w", err)
	}

	// 4. 执行SQL脚本创建表结构
	if err := executeSQLScript(config.DB, "db/init.sql"); err != nil {
		_ = config.DB.Close()
		return fmt.Errorf("执行初始化SQL脚本失败: %w", err)
	}

	// 5. 配置连接池
	config.DB.SetMaxOpenConns(20)
	config.DB.SetMaxIdleConns(10)
	config.DB.SetConnMaxLifetime(30 * time.Minute)
	config.DB.SetConnMaxIdleTime(10 * time.Minute)

	log.Printf("成功连接到数据库: %s", config.DBConfigInstance.Name)
	return nil
}

// 执行SQL脚本文件
func executeSQLScript(db *sql.DB, filePath string) error {
	// 读取SQL文件内容
	sqlContent, err := os.ReadFile(filePath)
	if err != nil {
		return fmt.Errorf("读取SQL文件失败: %w", err)
	}

	// 分割SQL语句（简单处理，适用于标准分号结尾的SQL）
	sqlStatements := strings.Split(string(sqlContent), ";")

	// 开启事务执行所有SQL
	tx, err := db.Begin()
	if err != nil {
		return fmt.Errorf("开启事务失败: %w", err)
	}
	defer func() {
		if r := recover(); r != nil {
			_ = tx.Rollback()
		}
	}()

	for _, stmt := range sqlStatements {
		stmt = strings.TrimSpace(stmt)
		if stmt == "" {
			continue
		}
		_, err := tx.Exec(stmt)
		if err != nil {
			_ = tx.Rollback()
			return fmt.Errorf("执行SQL语句失败: %s, 错误: %w", stmt, err)
		}
	}

	if err := tx.Commit(); err != nil {
		return fmt.Errorf("提交事务失败: %w", err)
	}

	fmt.Println("SQL脚本执行成功")
	return nil
}

// CloseDB 关闭数据库连接
func CloseDB() error {
	if config.DB != nil {
		return config.DB.Close()
	}
	return nil
}
